#!/bin/bash

# parameters
CLI=$1
CONTAINER_NAME=$2
GUEST_MEMORY_SIZE=(2048*1024*1024)

if [ `id -u` -ne 0 ]; then
	echo "Must be run as root!"
	exit 1
fi

if [ $# -ne 2 ];
then
    echo "Usage:"
    echo "sudo ./dump-kata-memory.sh CLI(docker or nerdctl or crictl) CONTAINER_NAME"
    exit 1
fi

echo_cmd() {
	cmd="$*"
	echo -e "\n\033[1;4;31m$cmd\033[0m"
	sleep 1.5
}

clear
# List all VM
tput rmam
if [ ${CLI} == "crictl" ]; then
	CONTAINER_ID=($($CLI -r unix:///run/containerd/containerd.sock pods --name "$CONTAINER_NAME" | awk 'NR == 2' | awk -F " " '{print $1}'))
else
	CONTAINER_ID=($($CLI ps -a | grep -w "$CONTAINER_NAME" | awk -F " " '{print $1}'))
fi
GUEST_NAME=sandbox-$CONTAINER_ID
echo $GUEST_NAME
#cmd="ps axo user,pid,vsz,command | grep qemu-system-x86_64"
cmd="ps axo user,pid,vsz,command | grep $GUEST_NAME"
echo_cmd $cmd
#ps axo user,pid,vsz,command | grep qemu-system-x86_64
ps axo user,pid,vsz,command | grep $GUEST_NAME
#sleep 1
# Get all VM pids
#vm_pid_array=($(ps axo user,pid,vsz,command | grep "qemu-system-x86_64" | awk -F " " '{print $2}'))
vm_pid_array=($(ps axo user,pid,vsz,command | grep "$GUEST_NAME" | awk -F " " '{print $2}'))
#echo ${vm_pid_array[@]}

# Iterate vm_pid_array to dump memory
for(( i=0;i<${#vm_pid_array[@]};i++)) do
	proc_map_path=/proc/${vm_pid_array[i]}/maps
	# Get the start HVA of a VM memory
	if [ -f $proc_map_path ];then
		sev_guest_str=($(ps axo user,pid,vsz,command | grep "${vm_pid_array[i]}" | grep "qemu-system-x86_64" | grep "$GUEST_NAME"))
		if [ ! -z ${sev_guest_str} ]; then
			echo -e "\n$GUEST_NAME PID: \e[1;4;34m${vm_pid_array[i]}\e[0m";
			sleep 3
			#echo -e "\nCSV VM PID: ${vm_pid_array[i]}";
		#else
			#echo -e "\nStandard VM PID: ${vm_pid_array[i]}";
		fi
		clear
		cmd="cat $proc_map_path"
		#echo_cmd $cmd
		echo -e "\n\033[1;4;31m$cmd\033[0m"
		#cat $proc_map_path | head -28
		cat $proc_map_path | awk -F " " '$2 != "rw-s"' > maps
		cat maps | while read line
		do
			echo $line | awk -F " " '{printf("%s %s",$1,$2)}' >> sort_maps
			start_hva=($(echo $line | \
				awk -F " " '{print $1}' | \
				awk -F "-" '{print "0x"$2"-""0x"$1}'| \
				awk -F "-" '{printf("%s",$2)}' | \
				awk -F "x" '{print $2}' \
				))
			#echo $start_hva
			((start_hva=0x$start_hva))
			end_hva=($(echo $line | \
				awk -F " " '{print $1}' | \
				awk -F "-" '{print "0x"$2"-""0x"$1}'| \
				awk -F "-" '{printf("%s",$1)}' | \
				awk -F "x" '{print $2}' \
				))
			#echo $end_hva
			((end_hva=0x$end_hva))
			((mem_size=$end_hva-$start_hva))
			#echo $mem_size
			printf " %.8x " $mem_size >> sort_maps
			echo $line | awk -F " " '{print $4,$5,$6}' >> sort_maps
		done
		echo -e "address\t\t\t  perms\toffset\tdev   inode\tpathname"
		sort -nrk3,3 sort_maps > sorted_maps
		head -15 sorted_maps
		# get vm_start_hva from sorted_maps
		vm_start_hva=($(head -1 sorted_maps | \
			awk -F " " '{print $1}' | \
			awk -F "-" '{print $1}'))
		#echo "vm_start_hva" $vm_start_hva
		rm -rf maps sort_maps sorted_maps
		echo -e "\nVM memory start: \e[1;4;34m0x$vm_start_hva\e[0m"
		vm_start_hva_hex=`echo $vm_start_hva`
		((vm_start_hva=0x$vm_start_hva))
		((vm_start_hva=($vm_start_hva/4096)))
		#echo $vm_start_hva
		sleep 4
		clear
		#set -x
		# Dump the VM memory of the first page
		cmd="dd if=/proc/${vm_pid_array[i]}/mem bs=4096 count=1 skip=(0x$vm_start_hva_hex/4096) | hexdump"
		echo_cmd $cmd
		dd if=/proc/${vm_pid_array[i]}/mem bs=4096 count=1 skip=$vm_start_hva | hexdump -C -v | head -14
		#dd if=/proc/${vm_pid_array[i]}/mem bs=4096 count=1 skip=$vm_start_hva > vm_first_page
		#set +x
	fi
done;
tput smam
